﻿using AntdUI;
using BST250301TestStand.Models;
using BST250301TestStand.Models.Helpers;
using BST250301TestStand.Models.Utils;
using Google.Protobuf.Collections;
using HslControls.Charts;
using Microsoft.IdentityModel.Tokens;
using Mysqlx.Crud;
using NPOI.SS.Formula.Functions;
using ScottPlot;
using ScottPlot.Plottables;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Linq;

namespace BST250301.Views
{
    public partial class ShowRealList : UserControl
    {
        public bool submit;
        public bool _auto;
        private static ProjectItem _item;
        private static AntList<ProjectItem> antList = new AntList<ProjectItem>();
        private static List<ShowDataRecord> showRealDataList = new List<ShowDataRecord>();
        private MouseEventHandler _mouseMoveHandler;

        private static ShowRealList _instance;
        public static ShowRealList Instance
        {
            get
            {
                if (_instance == null || _instance.IsDisposed)
                    _instance = new ShowRealList(_item, antList, false);
                return _instance;
            }
        }
        // ScottPlot.Plottables.SignalXY MySignaY;
        // ScottPlot.Plottables.SignalXY MySignaC;
        // ScottPlot.Plottables.Crosshair MyCrosshairY;
        // ScottPlot.Plottables.Crosshair MyCrosshairC;
        // //ScottPlot.Plottables.Crosshair MyCrosshair;
        // ScottPlot.Plottables.Marker MyHighlightMarkerY;
        // ScottPlot.Plottables.Marker MyHighlightMarkerC;
        //// ScottPlot.Plottables.Marker MyHighlightMarker;
        // ScottPlot.Plottables.Text MyHighlightTextY;
        // ScottPlot.Plottables.Text MyHighlightTextC;
        // //ScottPlot.Plottables.Text MyHighlightText;
        // //public ShowRealList(double[] xs, double[] ys)

        public ShowRealList(ProjectItem item, AntList<ProjectItem> list, bool autoPhoto, int seconds = 0)
        {
            InitializeComponent();
            _item = item;
            _auto = autoPhoto;
            antList = list;
            InitData(item.TemplateName);

            Task.Delay(50);
            //if (autoPhoto)
            //{
            //    TakePhoto(false);
            //    Task.Delay(50);
            //    submit = true;
            //    Thread.Sleep(10);
            //    this.Dispose();
            //}
        }
        private async Task InitShowRealData(List<ShowDataRecord> list, bool is2to1, float xParesue)
        {
            ClearPlot();

            int hexadd = 0xF00f00;
            var listMySignalY = new List<ScottPlot.Plottables.SignalXY>();
            var listMySignalC = new List<ScottPlot.Plottables.SignalXY>();
            if (list == null)
                return;
            string yTxt = string.Empty;
            for (int i = 0; i < list.Count; i++)
            {

                var item = list[i];
                if (item.From == "TCU")
                {
                    double[] ms = item.ListX.ToArray();
                    double[] dataY = item.ListY.ToArray();
                    //double[] dataC = item.ListC.ToArray();

                    if (item.AppName.Contains("Pressure"))
                    {
                        var sigY = new SignalXY(null);// formsPlot1.Plot.Add.SignalXY(ms, dataY);
                        //var sigC = formsPlot1.Plot.Add.SignalXY(ms, dataC);
                        if (xParesue > 1)
                        {
                            var db = dataY.Select(n => n * xParesue).ToArray();
                            sigY = formsPlot1.Plot.Add.SignalXY(ms, db);
                            float xpar = 1 / xParesue;
                            sigY.LegendText = $"{item.Title} 反馈/{xpar.ToString("F4")}{item.Unit}";
                        }
                        else
                        {
                            sigY = formsPlot1.Plot.Add.SignalXY(ms, dataY);
                            sigY.LegendText = $"{item.Title} 反馈/{item.Unit}";
                        }

                        if (!is2to1)
                        {
                            var yAxis2 = formsPlot1.Plot.Axes.AddLeftAxis();
                            sigY.Axes.XAxis = formsPlot1.Plot.Axes.Bottom; // standard X axis
                            sigY.Axes.YAxis = yAxis2; // custom Y axis
                            yAxis2.LabelText = $"Secondary Y Axis:{item.Title} {item.Unit}";
                        }
                        //int hex = 0x00AF0F;
                        //sigYY.Color = ScottPlot.Color.FromHex(hex.ToString("X"));
                        //sigY.Color = ScottPlot.Color.FromHex(hex.ToString("X"));
                        //hex = hex + hexadd;
                        //sigC.Color = ScottPlot.Color.FromHex(hex.ToString("X"));
                        // sigC.LegendText = $"{item.Title} 控制/{item.Unit}";
                        //sigYY.LegendText = $"{item.Title} {item.Unit}";

                        sigY.LineWidth = 2;
                        //sigC.LineWidth = 2;
                        listMySignalY.Add(sigY);
                        //listMySignalC.Add(sigC);
                    }
                    else
                    {
                        var sigY = formsPlot1.Plot.Add.SignalXY(ms, dataY);
                        //var sigC = formsPlot1.Plot.Add.SignalXY(ms, dataC);

                        //int hex = 0x0F0F0F;
                        //sigY.Color = ScottPlot.Color.FromHex(hex.ToString("X"));
                        sigY.LegendText = $"{item.Title} 反馈/{item.Unit}";
                        // hex = hex + hexadd;
                        //sigC.Color = ScottPlot.Color.FromHex(hex.ToString("X"));
                        //sigC.LegendText = $"{item.Title} 控制/{item.Unit}";

                        sigY.LineWidth = 2;
                        //sigC.LineWidth = 2;

                        listMySignalY.Add(sigY);
                        //listMySignalC.Add(sigC);

                        yTxt += $" {item.Title} {item.Unit}";
                        formsPlot1.Plot.YLabel($"{yTxt}");
                    }
                    //formsPlot1.Plot.YLabel($"{item.Unit}");

                    formsPlot1.Plot.ShowLegend();
                }

                if (item.From == "PLC")
                {
                    double[] ms = item.ListX.ToArray();
                    double[] dataY = item.ListY.ToArray();
                    //double[] dataC = item.ListC.ToArray();

                    var sigY = formsPlot1.Plot.Add.SignalXY(ms, dataY);
                    //var sigC = formsPlot1.Plot.Add.SignalXY(ms, dataC);
                    //int hex = 0xF0F0F0;
                    //sigY.Color = ScottPlot.Color.FromHex(hex.ToString("X"));
                    sigY.LegendText = $"{item.Title} 反馈/{item.Unit}";
                    //hex = hex + hexadd;
                    //sigC.Color = ScottPlot.Color.FromHex(hex.ToString("X"));
                    //sigC.LegendText = $"{item.Title} 控制/{item.Unit}";

                    sigY.LineWidth = 2;
                    //sigC.LineWidth = 2;

                    listMySignalY.Add(sigY);
                    //listMySignalC.Add(sigC);

                    formsPlot1.Plot.YLabel($"{item.Unit}");
                    formsPlot1.Plot.ShowLegend();
                }

                hexadd += hexadd;
            }

            var xAxis = formsPlot1.Plot.Axes.Bottom;
            xAxis.MajorTickStyle.Length = 1;
            formsPlot1.Plot.Font.Automatic();
            formsPlot1.Refresh();
            if (listMySignalY.Count == 0)
            {
                //MessageBox.Show("当前数据无效，请重试");
                return;
            }


            var listMyCrosshairY = new List<ScottPlot.Plottables.Crosshair>();
            //var listMyCrosshairC = new List<ScottPlot.Plottables.Crosshair>();

            var listMyHighlightMarkerY = new List<ScottPlot.Plottables.Marker>();
            //var listMyHighlightMarkerC = new List<ScottPlot.Plottables.Marker>();

            var listMyHighlightTextY = new List<ScottPlot.Plottables.Text>();
            //var listMyHighlightTextC = new List<ScottPlot.Plottables.Text>();
            foreach (var item in listMySignalY)
            {
                var mycrosshairy = formsPlot1.Plot.Add.Crosshair(0, 0);
                mycrosshairy.IsVisible = false;
                mycrosshairy.MarkerShape = MarkerShape.OpenCircle;
                mycrosshairy.MarkerSize = 15;
                listMyCrosshairY.Add(mycrosshairy);

                var myHighlightMarkerY = formsPlot1.Plot.Add.Marker(0, 0);
                myHighlightMarkerY.Shape = MarkerShape.OpenCircle;
                myHighlightMarkerY.Size = 17;
                myHighlightMarkerY.LineWidth = 2;
                listMyHighlightMarkerY.Add(myHighlightMarkerY);

                var myHighlightTextY = formsPlot1.Plot.Add.Text($"0,0", 0, 0);
                myHighlightTextY.LabelAlignment = Alignment.LowerLeft;
                myHighlightTextY.LabelBold = true;
                myHighlightTextY.OffsetX = 7;
                myHighlightTextY.OffsetY = -7;
                listMyHighlightTextY.Add(myHighlightTextY);
            }
            //foreach (var item in listMySignalC)
            //{
            //    var mycrosshairC = formsPlot1.Plot.Add.Crosshair(0, 0);
            //    mycrosshairC.IsVisible = false;
            //    mycrosshairC.MarkerShape = MarkerShape.OpenCircle;
            //    mycrosshairC.MarkerSize = 15;
            //    listMyCrosshairC.Add(mycrosshairC);

            //    var myHighlightMarkerC = formsPlot1.Plot.Add.Marker(0, 0);
            //    myHighlightMarkerC.Shape = MarkerShape.OpenCircle;
            //    myHighlightMarkerC.Size = 17;
            //    myHighlightMarkerC.LineWidth = 2;
            //    listMyHighlightMarkerC.Add(myHighlightMarkerC);

            //    var myHighlightTextC = formsPlot1.Plot.Add.Text($"0,0", 0, 0);
            //    myHighlightTextC.LabelAlignment = Alignment.LowerLeft;
            //    myHighlightTextC.LabelBold = true;
            //    myHighlightTextC.OffsetX = 7;
            //    myHighlightTextC.OffsetY = -7;
            //    listMyHighlightTextC.Add(myHighlightTextC);
            //}
            //formsPlot1.MouseMove += (s, e) =>
            _mouseMoveHandler = (s, e) =>
            {
                // determine where the mouse is and get the nearest point
                Pixel mousePixel = new(e.Location.X, e.Location.Y);
                Coordinates mouseLocation = formsPlot1.Plot.GetCoordinates(mousePixel);

                var listNewarstY = new List<DataPoint>();

                for (int i = 0; i < listMySignalY.Count; i++)
                {
                    var item = listMySignalY[i];
                    if (item.LegendText.Contains("Pressure"))
                    {

                    }
                    DataPoint nearestY = item.Data.GetNearest(mouseLocation, formsPlot1.Plot.LastRender);
                    listNewarstY.Add(nearestY);
                    if (nearestY.IsReal)
                    {
                        listMyCrosshairY[i].IsVisible = true;
                        listMyCrosshairY[i].Position = nearestY.Coordinates;

                        listMyHighlightMarkerY[i].IsVisible = true;
                        listMyHighlightMarkerY[i].Location = nearestY.Coordinates;
                        listMyHighlightMarkerY[i].Location = nearestY.Coordinates;

                        listMyHighlightTextY[i].IsVisible = true;
                        listMyHighlightTextY[i].Location = nearestY.Coordinates;
                        listMyHighlightTextY[i].LabelText = $"{item.LegendText}, x={nearestY.X:0.####}, y={nearestY.Y:0.####}";

                        string sec = string.Empty;
                        for (int k = 0; k < listMyHighlightTextY.Count; k++)
                        {
                            if (k == i)
                            {
                                listMyHighlightTextY[k].LabelText = $"{item.LegendText}, x={nearestY.X:0.####}, y={nearestY.Y:0.####}";
                                continue;
                            }
                            var itemOther = listMySignalY[k];
                            var ret = itemOther.GetNearestX;
                            DataPoint nearestSec = itemOther.Data.GetNearestX(mouseLocation, formsPlot1.Plot.LastRender);
                            sec += $";\n附近数据：{itemOther.LegendText}, x={nearestSec.X:0.####}, y={nearestSec.Y:0.####}";
                        }

                        listMyHighlightTextY[i].LabelText = $"{item.LegendText}, x={nearestY.X:0.####}, y={nearestY.Y:0.####} {sec}";
                        listMyHighlightTextY[i].LabelFontName = Fonts.Detect(listMyHighlightTextY[i].LabelText);
                        listMyHighlightTextY[i].LabelFontSize = 18f;
                        sec = string.Empty;

                    }
                    if (!nearestY.IsReal && listMyCrosshairY[i].IsVisible)
                    {
                        listMyHighlightTextY[i].LabelText = $"{item.LegendText}, x={nearestY.X:0.####}, y={nearestY.Y:0.####}";
                        listMyCrosshairY[i].IsVisible = false;
                        listMyHighlightMarkerY[i].IsVisible = false;
                        listMyHighlightTextY[i].IsVisible = false;
                        // Text = $"No point selected";
                    }
                }

                //var listNewarstC = new List<DataPoint>();
                //for (int i = 0; i < listMySignalC.Count; i++)
                //{
                //    var item = listMySignalC[i];

                //    DataPoint nearestC = item.Data.GetNearest(mouseLocation, formsPlot1.Plot.LastRender);
                //    listNewarstC.Add(nearestC);
                //    if (nearestC.IsReal)
                //    {
                //        listMyCrosshairC[i].IsVisible = true;
                //        listMyCrosshairC[i].Position = nearestC.Coordinates;

                //        listMyHighlightMarkerC[i].IsVisible = true;
                //        listMyHighlightMarkerC[i].Location = nearestC.Coordinates;
                //        listMyHighlightMarkerC[i].Location = nearestC.Coordinates;

                //        listMyHighlightTextC[i].IsVisible = true;
                //        listMyHighlightTextC[i].Location = nearestC.Coordinates;
                //        listMyHighlightTextC[i].LabelText = $"{item.LegendText} {nearestC.X:0.##}s, {nearestC.Y:0.##}";
                //        listMyHighlightTextC[i].LabelFontName = Fonts.Detect(listMyHighlightTextC[i].LabelText);
                //        listMyHighlightTextC[i].LabelFontSize = 18f;
                //    }
                //    if (!nearestC.IsReal && listMyCrosshairC[i].IsVisible)
                //    {
                //        listMyCrosshairC[i].IsVisible = false;
                //        listMyHighlightMarkerC[i].IsVisible = false;
                //        listMyHighlightTextC[i].IsVisible = false;
                //        // Text = $"No point selected";
                //    }
                //}
                formsPlot1.Plot.Font.Automatic();
                formsPlot1.Refresh();

            };
            formsPlot1.MouseMove += _mouseMoveHandler;
        }

        private void ClearPlot()
        {
            formsPlot1.MouseMove -= _mouseMoveHandler;
            formsPlot1.Plot.Clear();
            // 清空自定义 Y 轴 (所有 AddLeftAxis)
            //formsPlot1.Plot.Axes.ClearSecondaryAxes();
            //formsPlot1.Plot.Axes.ClearCustomAxes();


            // 1. 获取所有左侧的 Y 轴 (ScottPlot.Edge.Left)
            // 列表中元素的类型是 ScottPlot.IAxis
            var leftAxes = formsPlot1.Plot.Axes.GetAxes(ScottPlot.Edge.Left);

            // 2. 识别并移除所有“非默认”的 Y 轴
            var yAxesToRemove = new List<ScottPlot.IYAxis>(); // 注意：假设 IYAxis 位于 ScottPlot 命名空间

            foreach (var axis in leftAxes)
            {
                // 检查轴是否是默认的 Left 轴（默认轴是 formsPlot1.Plot.Axes.Left）
                if (axis != formsPlot1.Plot.Axes.Left)
                {
                    // 尝试将通用的 IAxis 转换为 IYAxis
                    if (axis is ScottPlot.IYAxis yAxis)
                    {
                        yAxesToRemove.Add(yAxis);
                    }
                    // 如果不是 IYAxis，可能说明这个对象不是可移除的轴，忽略
                }
            }

            // 3. 遍历列表并移除
            foreach (var yAxis in yAxesToRemove)
            {
                formsPlot1.Plot.Axes.Remove(yAxis);
            }

            formsPlot1.Refresh();

        }

        private async void InitData(string setname)
        {
            //var plateList = DB.GetTestTemplate(planname);
            //if (plateList.Count > 0)
            //{

            //}
            var list = DB.GetTemPlatestep(MainWindow.configapp.PlanName, setname);
            selectProjiecname.Items.Clear();
            foreach (var item in list)
            {
                selectProjiecname.Items.Add(item.ProjectName);
            }
            selectProjiecname.Text = _item.Name;
            InitShowRealData(_item.ListShowRealData, checkbox2to1.Checked, (float)inputNumberXpar.Value);
        }
        private void buttonCamera_Click(object sender, EventArgs e)
        {
            TakePhoto(true);
        }
        private async Task TakePhoto(bool isopen)
        {
            var dt = DateTime.Now;
            var path = $"D:\\Record\\{dt.ToString("yyyy")}\\{dt.ToString("MM")}\\{dt.ToString("dd")}\\Images\\";
            if (CSV.CreatePath(path))
            {
                string fullfie = $"{path}{_item.TemplateName}_{_item.Name}_SN_{_item.SN}_{dt.ToString("HH_mm_ss")}.png";
                formsPlot1.Plot.SavePng(fullfie, 1200, 800);
                if (isopen)
                {
                    Process.Start(new ProcessStartInfo(fullfie) { UseShellExecute = true });
                    //Process.Start(new ProcessStartInfo($"{path}PLC_SN_{_item.SN}_{dt.ToString("HH_mm_ss")}.png") { UseShellExecute = true });
                }
            }
        }

        private void selectProjiecname_SelectedIndexChanged(object sender, IntEventArgs e)
        {
            this.checkboxSpeed.Checked = true;
            if (selectProjiecname.SelectedValue == null)
                return;
            string name = selectProjiecname.SelectedValue.ToString().Trim();
            CheckedChanged(name);
        }
        private void buttonClose_Click_1(object sender, EventArgs e)
        {
            submit = true;
            Thread.Sleep(10);
            this.Dispose();
        }

        private static List<ShowDataRecord> GetLowPassFilter(double alpha, List<ShowDataRecord> list)
        {
            var filter = new LowPassFilter(alpha);
            var newList = new List<ShowDataRecord>();
            try
            {
                foreach (var itemShow in list)
                {
                    var listY = new List<double>();
                    var listC = itemShow.ListC;
                    var listX = itemShow.ListX;
                    var ListS = itemShow.ListS;
                    if (itemShow.ListY != null)
                    {
                        foreach (var dy in itemShow.ListY)
                        {
                            listY.Add(filter.Filter(dy));
                        }
                    }
                    //if (itemShow.ListX != null)
                    //{
                    //    foreach (var dx in itemShow.ListX)
                    //    {
                    //        listX.Add(filter.Filter(dx));
                    //    }
                    //}
                    //if (itemShow.ListC != null)
                    //{
                    //    foreach (var dc in itemShow.ListC)
                    //    {
                    //        listC.Add(filter.Filter(dc));
                    //    }
                    //}
                    //if (itemShow.ListS != null)
                    //{
                    //    foreach (var ds in itemShow.ListS)
                    //    {
                    //        ListS.Add(filter.Filter(ds));
                    //    }
                    //}
                    newList.Add(new ShowDataRecord
                    {
                        From = itemShow.From,
                        AppName = itemShow.AppName,
                        Title = itemShow.Title,
                        Unit = itemShow.Unit,
                        ListX = listX,
                        ListY = listY,
                        ListC = listC,
                        ListS = listC
                    });
                }
            }
            catch (Exception)
            {

                throw;
            }
            return newList;
        }
        private void checkboxSpeed_CheckedChanged(object sender, BoolEventArgs e)
        {
            if (selectProjiecname.SelectedValue == null)
                return;
            string name = selectProjiecname.SelectedValue.ToString().Trim();
            CheckedChanged(name);
        }
        private void CheckedChanged(string name)
        {
            if (checkboxSpeed.Checked)
            {
                var filter = new LowPassFilter(alpha: (double)this.inputNumberFilter.Value);

                foreach (var item in antList)
                {
                    if (name == item.Name)
                    {
                        List<ShowDataRecord> newList = GetLowPassFilter((double)this.inputNumberFilter.Value, item.ListShowRealData);
                        InitShowRealData(newList, checkbox2to1.Checked, (float)inputNumberXpar.Value);
                        return;
                    }
                }
            }
            else
            {
                foreach (var item in antList)
                {
                    if (name == item.Name)
                    {
                        InitShowRealData(item.ListShowRealData, checkbox2to1.Checked, (float)inputNumberXpar.Value);
                        return;
                    }
                }
            }

        }

        private void inputNumberFilter_ValueChanged(object sender, DecimalEventArgs e)
        {
            if (selectProjiecname.SelectedValue == null)
                return;
            string name = selectProjiecname.SelectedValue.ToString().Trim();
            if (checkboxSpeed.Checked)
            {
                var filter = new LowPassFilter(alpha: (double)this.inputNumberFilter.Value);

                foreach (var item in antList)
                {
                    if (name == item.Name)
                    {
                        List<ShowDataRecord> newList = GetLowPassFilter((double)this.inputNumberFilter.Value, item.ListShowRealData);
                        InitShowRealData(newList, checkbox2to1.Checked, (float)inputNumberXpar.Value);
                        return;
                    }
                }
            }
        }

        private void checkbox1_CheckedChanged(object sender, BoolEventArgs e)
        {
            if (selectProjiecname.SelectedValue == null)
                return;
            string name = selectProjiecname.SelectedValue.ToString().Trim();
            CheckedChanged(name);
        }

        private void inputNumberXpar_ValueChanged(object sender, DecimalEventArgs e)
        {

            if (selectProjiecname.SelectedValue == null)
                return;
            string name = selectProjiecname.SelectedValue.ToString().Trim();
            CheckedChanged(name);
        }

        private void ShowRealList_Load(object sender, EventArgs e)
        {
            if (_auto)
            {
                TakePhoto(false);
                Task.Delay(50);
                submit = true;
                Thread.Sleep(10);
                this.Dispose();
            }
        }
    }
}